<template>
	<picker-view
		class="date-picker-view"
		indicator-style="height: 40px;"
		:value="state.indexs"
		immediate-change
		@change="handleChange"
		v-if="state.visible"
	>
		<picker-view-column v-for="(items, index) of state.datas" :key="index">
			<view class="picker-view-item" v-for="item of items" :key="item">
				<text>{{ item }}{{ unit[index] }}</text>
			</view>
		</picker-view-column>
	</picker-view>
</template>

<script>
const config = {
  k0: {
    min: 1600,
    max: 9999,
  },
  k1: {
    min: 1,
    max: 12,
  },
  k2: {
    min: 1,
    max: 31,
  },
  k3: {
    min: 0,
    max: 23,
  },
  k4: {
    min: 0,
    max: 59,
  },
  k5: {
    min: 0,
    max: 59,
  },
};

export default {
  props: {
    value: String,
    min: String,
    max: String,
    format: {
			type: String,
			default: 'yyyy-MM-dd HH:mm'
		},
    unit: {
      type: Array,
      default: () => ["年", "月", "日", "时", "分"],
    },
  },
  data() {
    return {
      state: {
        indexs: [0, 0, 0, 0, 0],
        datas: [],
        startDate: [],
        endDate: [],
        minDate: [],
        maxDate: [],
				visible: false,
      },
    };
  },
  methods: {
    // 初始化
    init() {
      this.state.startDate = this.getCurrentDate(this.value);
      this.state.minDate = this.getMinDate(this.state.startDate, this.min);
      this.state.maxDate = this.getMaxDate(this.state.startDate, this.max);

      const _datas = [];
      for (let i = 0, len = this.state.indexs.length; i < len; i++) {
        _datas.push(
          this.initItems(
            this.state.minDate,
            this.state.maxDate,
            this.state.startDate,
            i
          )
        );
      }

      this.state.datas = _datas;
      this.initIndex();
			this.state.visible = true;
    },
    // 获取当前日期
    getCurrentDate(str) {
      const date = new Date();
      const arr = [
        date.getFullYear(),
        date.getMonth() + 1,
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
      ];
      if (str) {
        str = str.replace(/[\s|-|\/|:]/g, "-");
        const strArr = str.split("-");
        strArr.forEach((item, index) => {
          arr[index] = Number(item);
        });
      }
      return arr;
    },
    // 设置最小日期
    getMinDate(date, str) {
      const arr = [date[0] - 10, 1, 1, 0, 0, 0];
      if (str) {
        str = str.replace(/[\s|-|\/|:]/g, "-");
        const strArr = str.split("-");
        strArr.forEach((item, index) => {
          arr[index] = Number(item);
        });
      }
      return arr;
    },
    // 设置最大日期
    getMaxDate(date, str) {
      const arr = [date[0] + 10, 12, 31, 23, 59, 59];
      if (str) {
        str = str.replace(/[\s|-|\/|:]/g, "-");
        const strArr = str.split("-");
        strArr.forEach((item, index) => {
          arr[index] = Number(item);
        });
      }
      return arr;
    },
    initIndex() {
      this.state.datas.forEach((items, index) => {
        const idx = items.findIndex(
          (item) => item === this.state.startDate[index]
        );
        this.state.indexs[index] = idx < 0 ? 0 : idx;
        this.state.startDate[index] = items[this.state.indexs[index]];
      });
    },
    initItems(min, max, current, index) {
      let _arr = [],
        start = 0,
        end = 0;
      if (index === 0) {
        start = min[0];
        end = max[0];
      } else {
        let flagMin = true,
          flagMax = true;
        for (let i = 0; i < index; i++) {
          if (current[i] !== min[i]) {
            flagMin = false;
            break;
          }
        }
        for (let i = 0; i < index; i++) {
          if (current[i] !== max[i]) {
            flagMax = false;
            break;
          }
        }
        start = flagMin ? min[index] : config["k" + index].min;
        end = flagMax
          ? max[index]
          : index === 2
          ? this.getCountDays(current)
          : config["k" + index].max;
      }

      for (let i = start; i <= end; i++) {
        _arr.push(i);
      }

      return _arr;
    },
    // 获取当月天数
    getCountDays(date) {
      const curDate = new Date(date[0], date[1] - 1, 1, 0, 0);
      // 获取当前月份
      var curMonth = curDate.getMonth();
      // 实际月份比curMonth大1，下面将月份设置为下一个月
      curDate.setMonth(curMonth + 1);
      // 将日期设置为0，表示自动计算为上个月（这里指的是当前月份）的最后一天
      curDate.setDate(0);
      // 返回当前月份的天数
      return curDate.getDate();
    },
		// 变化处理函数
    handleChange(e) {
      e.detail.value.forEach((item, index) => {
        this.state.startDate[index] = this.state.datas[index][item] ?? 1;
      });
      const _datas = [];
      for (let i = 0, len = e.detail.value.length; i < len; i++) {
        _datas.push(
          this.initItems(this.state.minDate, this.state.maxDate, this.state.startDate, i)
        );
      }
      this.state.datas = _datas;
      this.initIndex();
			
			const date = this.state.startDate
			const formateStr = this.getFormateVal(date)
			this.$emit('input', formateStr)
    },
		getFormateVal(date) {
			let ret, fmt = this.format;
			const opt = {
				"y+": date[0].toString(), // 年
				"M+": date[1].toString(), // 月
				"d+": date[2].toString(), // 日
				"H+": date[3].toString(), // 时
				"m+": date[4].toString(), // 分
			};
			for (let k in opt) {
				ret = new RegExp("(" + k + ")").exec(fmt);
				if (ret) {
					fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
				}
			}
			return fmt;
		}
  },
};
</script>

<style lang="scss" scoped>
.date-picker-view {
  height: 400rpx;
  padding: 0 24rpx 0 62rpx;
  .picker-view-item {
    width: 110rpx;
    font-weight: 400;
    font-size: 32rpx;
    line-height: 40px;
    color: #000000e5;
    text-align: center;
  }
}
</style>
